﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;

namespace GoogleReaderAccess
{
    public class WebRequestState
    {
        public HttpWebRequest Request
        {
            get { return request; }
            set { request = value; }
        }

        private HttpWebRequest request;
    }

    //Delegates
    public delegate void LoginExecutedInternal(object sender, LoginEventArgs e);

    public class SessionServices
    {
        public SessionServices()
        {
        }
        public SessionServices(string userName, string password)
        {
            this.userName = userName;
            this.password = password;
        }

        public void doLogin(string userName, string password)
        {
            this.userName = userName;
            this.password = password;
            doLogin();
        }

        public void doLogin()
        {
            if (userName.Length == 0 && password.Length == 0)
                throw new ArgumentException("Unable to perform login without userName and password set");
            try
            {
                string url = string.Format("https://www.google.com/accounts/ClientLogin?service=reader&Email={0}&Passwd={1}", userName, password);
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "GET";

                WebRequestState state = new WebRequestState();
                state.Request = req;
                IAsyncResult res = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(HandleLoginResponse), state);
            }
            catch (WebException ex)
            {
                
            }
            catch (Exception ex)
            { 
            
            }

        }

        private void HandleLoginResponse(IAsyncResult asyncResult)
        {
            try
            {
                WebRequestState state = (WebRequestState)asyncResult.AsyncState;
                HttpWebRequest request = state.Request;
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string responseString = reader.ReadToEnd();
                response.Close();
                StringSplitOptions sso = StringSplitOptions.RemoveEmptyEntries;
                char[] splitchar = { '\n' };
                string[] lines = responseString.Split(splitchar, sso);
                foreach (string l in lines)
                {
                    splitchar[0] = '=';
                    string[] key_value = l.Split(splitchar, sso);
                    if (key_value.Length == 2)
                    {
                        if (key_value[0] == "LSID")
                            LSID = key_value[1];
                        else if (key_value[0] == "SID")
                            SID = key_value[1];
                        else if (key_value[0] == "Auth")
                            Auth = key_value[1];
                    }
                }
            }
            catch (WebException ex)
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(false, ex.Message);
                    LoginDone(this, e);
                }
                return;
            }
            catch (Exception ex)
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(false, ex.Message);
                    LoginDone(this, e);
                }
                return;
            }
            //So far so good. We double check that we have been able to parse useful information.
            if(SID.Length > 0 && LSID.Length > 0 && Auth.Length > 0)
            {
                getToken();
            }
            else
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(false, "Something went wrong");
                    LoginDone(this, e);
                }
            }
        }

        public void getToken()
        {
            string url = "http://www.google.com/reader/api/0/token";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "GET";
            req.Headers["Authorization"] = "GoogleLogin auth=" + Auth;

            WebRequestState state = new WebRequestState();
            state.Request = req;
            IAsyncResult res = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(HandleTokenResponse), state);
        }

        private void HandleTokenResponse(IAsyncResult asyncResult)
        {
            try
            {
                WebRequestState state = (WebRequestState)asyncResult.AsyncState;
                HttpWebRequest request = state.Request;
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                Token = reader.ReadToEnd();
                response.Close();
            }
            catch (WebException ex)
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(false, ex.Message);
                    LoginDone(this, e);
                }
                return;
            }
            catch (Exception ex)
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(false, ex.Message);
                    LoginDone(this, e);
                }
                return;
            }

            if (Token.Length > 0)
            {
                if (LoginDone != null)
                {
                    LoginEventArgs e = new LoginEventArgs(true, "");
                    LoginDone(this, e);
                }
            }
        }

        public event LoginExecutedInternal LoginDone;

        private string userName;
        private string password;
        public string LSID  { get; private set; }
        public string SID   { get; private set; }
        public string Auth  { get; private set; }
        public string Token { get; private set; }
    }
}
